﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Reflection;

using Agile;

namespace System
{
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}, OrderBy:{OrderBy}")]
    public abstract class Entity : Entity<string>, IEntity
    {
        public Entity()
        {
            ID = GuidHelper.NewSequentialGuid().ToString();
        }
    }
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}")]
    public abstract class Entity<TPrimaryKey> : IEntity<TPrimaryKey>
    {
        public Entity()
        {
            OrderBy = 0;
            AddTime = DateTime.Now;
        }
        /// <summary>
        /// 唯一标识
        /// </summary>
        [Description("唯一标识")]
        [Key]
        [Display(Name = "唯一标识")]
        public virtual TPrimaryKey ID { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        [Description("排序")]
        [Display(Name = "排序")]
        public virtual int OrderBy { get; set; }
        /// <summary>
        /// 添加时间
        /// </summary>
        [Description("添加时间")]
        [Display(Name = "添加时间")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}", ApplyFormatInEditMode = true)]
        public virtual DateTime AddTime { get; set; }

        public void Create()
        {
            if (ID == null) ID = default(TPrimaryKey);

            var entity = this as TreeEntity;
            if (entity != null)
            {
                if (string.IsNullOrWhiteSpace(entity.ParentID))
                {
                    entity.ParentID = Guid.Empty.ToString();
                }
            }

            var creationAudited = this as ICreationAudited;
            if (creationAudited != null)
            {
                var accountId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.UserID);
                if (accountId != null && accountId.Value.NotNull())
                {
                    creationAudited.AddUserID = accountId.Value.Trim();
                }
            }
        }
        public void Modify()
        {
            var creationAudited = this as IModificationAudited;
            if (creationAudited != null)
            {
                var accountId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.UserID);
                if (accountId != null && accountId.Value.NotNull())
                {
                    creationAudited.EditUserID = accountId.Value.Trim();
                }
                creationAudited.EditTime = DateTime.Now;
            }
        }
        public void Remove()
        {
            var entity = this as ISoftDelete;
            if (entity != null)
            {
                var accountId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.UserID);
                if (accountId != null && accountId.Value.NotNull())
                {
                    entity.DeleteUserID = accountId.Value.Trim();
                    entity.IsDelete = 1;
                }
                entity.DeleteTime = DateTime.Now;
            }
        }
        public override string ToString()
        {
            return $"[{GetType().Name} {ID}]";
        }
    }
    /// <summary>
    /// 树形
    /// </summary>
    [Serializable]
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}")]
    public abstract class TreeEntity : TreeEntity<string>
    {
        public TreeEntity()
        {
            ID = GuidHelper.NewSequentialGuid().ToString();
            ParentID = Guid.Empty.ToString();
        }
    }
    /// <summary>
    /// 树形
    /// </summary>
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}")]
    public abstract partial class TreeEntity<TPrimaryKey> : Entity
    {
        public TreeEntity()
        {

        }
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        public virtual string Name { get; set; }
        /// <summary>
        /// 上一级
        /// </summary>
        [Description("上一级")]
        [Display(Name = "上一级")]
        public TPrimaryKey ParentID { get; set; }
    }
}
